//
//  File Name : VMRPlayer.h
//  Date : 22.01.2012
//  Author : Mashura Alexander
//

#ifndef __VMRPLAYER_H__
#define __VMRPLAYER_H__

#include <Windows.h>
#include <vector>
#include <string>
#include <d3d9.h>
#include <d3dx9.h>
#include <objbase.h>
#include <streams.h>
#include <vmr9.h>

#include "IVideo.h"
#include "Primitive.h"
#include "Observer.h"

class DX;

struct IMediaControl;
struct IMediaEventEx;
struct IMediaSeeking;
struct IVMRSurfaceAllocatorNotify9;
struct IVMRFilterConfig9;
struct IBaseFilter;
struct IGraphBuilder;
struct ICaptureGraphBuilder2;
struct IDirect3DTexture9;
struct IDirect3DSurface9;

class VMRPlayer : public IVMRSurfaceAllocator9, IVMRImagePresenter9, IVideo, Primitive
{
public:
	//Observers						videoCompleteObservers;

public:
	VMRPlayer( std::wstring fileURL, bool preload = false, bool loopVideo = false );
	~VMRPlayer();

	std::wstring					fileURL();
	//void							setVideoComplete( bool value );
	bool							isVideoPlaying();
	bool							isLoopVideo();

	bool load();
	bool unload();
	bool play();
	bool stop();
	bool pause();
	
	LONGLONG	duration();
		
	LONGLONG	position() const;
	void		position( LONGLONG pos );

	void draw();

private: 
	// Alloc
	virtual HRESULT STDMETHODCALLTYPE InitializeDevice( 
			/* [in] */ DWORD_PTR dwUserID,
			/* [in] */ VMR9AllocationInfo *lpAllocInfo,
			/* [out][in] */ DWORD *lpNumBuffers);
	            
	virtual HRESULT STDMETHODCALLTYPE TerminateDevice( 
		/* [in] */ DWORD_PTR dwID);
	    
	virtual HRESULT STDMETHODCALLTYPE GetSurface( 
		/* [in] */ DWORD_PTR dwUserID,
		/* [in] */ DWORD SurfaceIndex,
		/* [in] */ DWORD SurfaceFlags,
		/* [out] */ IDirect3DSurface9 **lplpSurface);
	    
	virtual HRESULT STDMETHODCALLTYPE AdviseNotify( 
		/* [in] */ IVMRSurfaceAllocatorNotify9 *lpIVMRSurfAllocNotify);

	// IVMRImagePresenter9
	virtual HRESULT STDMETHODCALLTYPE StartPresenting( 
		/* [in] */ DWORD_PTR dwUserID);
	    
	virtual HRESULT STDMETHODCALLTYPE StopPresenting( 
		/* [in] */ DWORD_PTR dwUserID);
	    
	virtual HRESULT STDMETHODCALLTYPE PresentImage( 
		/* [in] */ DWORD_PTR dwUserID,
		/* [in] */ VMR9PresentationInfo *lpPresInfo);
		
	// IUnknown
	virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
		REFIID riid,
		void** ppvObject);

	virtual ULONG STDMETHODCALLTYPE AddRef();
	virtual ULONG STDMETHODCALLTYPE Release();
private:
	HANDLE							threadHandle;

#if defined(_DEBUG) || defined(DEBUG)
	HANDLE							hLogFile;
#endif

	IMediaControl*					pMediaControl;
	IMediaEventEx*					pMediaEvent;
	IMediaSeeking*					pMediaSeeking;
	IVMRSurfaceAllocatorNotify9*	pNotify;
	IVMRFilterConfig9*				pConfig;
	IBaseFilter*					pVMRfilter;
	IGraphBuilder*					pGraph;
	ICaptureGraphBuilder2*			pBuild;
	
	IDirect3DTexture9*				pVideoTexture;
	IDirect3DSurface9*				pVideoTexSurface;

	std::wstring					_fileURL;
	
private:

	IDirect3DTexture9*				videoTexture();
	IDirect3DSurface9*				videoTexSurface();
	
	static DWORD __stdcall	runFilterGraph( void* self );
private:
	// Alloc
	std::vector< IDirect3DSurface9* >	pSufaces;
	size_t								countSurfaces;
	long								m_refCount;
private:
	bool							_videoPlaying;
	CRITICAL_SECTION				_critical_section_video_playing;
	bool							_loopVideo;
};

#endif
